import json

from django.contrib.auth import login, logout
from django.shortcuts import render

# ***********用户名验证************


# Create your views here.
from django.http import HttpResponse, JsonResponse
from django.views import View
from django_redis import get_redis_connection
from django.core.mail import send_mail

from apps.goods.models import SKU
from apps.users.models import User
import re

from utlis.secret_key import generate_email_verify_token, check_email_token
from celery_tasks.email.tasks import celery_send_email
from utlis.views import LoginRequiredJSONMixin


class UsernameCountView(View):
    def get(self, request, username):
        # 手写判断用户名是否满足需求
        # if not re.match('[a-zA-Z0-9_-]{5,20}',username):
        #     return JsonResponse({'code':200,'errmsg':'用户名不满足需求'})

        count = User.objects.filter(username=username).count()

        return JsonResponse({'code': 0, 'count': count, 'errmsg': 'ok'})


# ********手机号验证************

class MobileCountView(View):
    def get(self, request, mobile):

        count = User.objects.filter(mobile=mobile).count()
        if count:
            return JsonResponse({'errmsg': '手机号已存在'})
        else:

            return JsonResponse({'code': 0, 'count': count, 'errmsg': 'ok'})


# **********用户注册**************

"""
分析

请求:json(用户名，密码，确认密码，手机号，是否同意协议)
业务逻辑:
    接收请求
    获取数据
    校验前端发送的json数据
    如果没问题数据入库
    用户名格式是否正确,是否重复
    密码格式
    密码是否一致
    手机号格式手机号是否重复
    是否同意协议
响应:
    响应注册结果

"""


class Zhuce(View):
    # 接收请求

    def post(self, request):
        # a = request.body
        # b = a.decode()
        import json
        # c = json.loads(b)
        json_dict = json.loads(request.body.decode())
        # 提取参数
        username = json_dict.get('username')
        password = json_dict.get('password')
        password2 = json_dict.get('password2')
        mobile = json_dict.get('mobile')
        allow = json_dict.get('allow')
        sms_code = json_dict.get('sms_code')

        # 验证参数

        if not all([username, password, password2, mobile, allow]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})

        if not re.match('[a-zA-Z0-9_-]{5,20}', username):
            return JsonResponse({'code': 400, 'errmsg': '用户名格式有误'})

        if not re.match('1[3-9]\d{9}', mobile):
            return JsonResponse({'code': 400, 'errmsg': '手机号格式有误'})

        if not re.match('[a-zA-z0-9]{8,20}', password):
            return JsonResponse({'code': 400, 'errmsg': '密码格式错误'})

        if password2 != password:
            return JsonResponse({'code': 400, 'errmsg': '密码不一致'})

        if allow != True:
            return JsonResponse({'code': 400, 'errmsg': '用户未勾选协议'})
        # 校验短信验证码
        a = get_redis_connection('code')
        b = a.get(mobile)  # bytes
        if not b:
            return JsonResponse({'code': 400, 'errmsg': '短信验证码失效'})
        if sms_code != b.decode():
            return JsonResponse({'code': 400, 'errmsg': '短信验证码有误'})

        # 数据入库
        user = User.objects.create_user(username=username, password=password, mobile=mobile)

        # django自带的状态保持的方法
        # from django.contrib.auth import login
        login(request, user)

        reponse = JsonResponse({'code': 0, 'errmsg': 'ok'})
        reponse.set_cookie('username', username)
        return reponse


# *************用户登录**********************


"""
请求:接收参数 验证参数
    
业务逻辑:判断用户名密码是否正确 设置session 

响应:返回json数据

"""


class LoginView(View):
    # 1.接收数据
    def post(self, request):
        json_dict = json.loads(request.body.decode())

        username = json_dict.get('username')
        password = json_dict.get('password')
        remembered = json_dict.get('remembered')
        # 验证数据
        if not all([username, password]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})

        # 3.验证用户名和密码
        # 手机号或者用户名登录
        # authenticate 根据USERNAME_FIELD来查询数据库
        if re.match('1[3-9]\d{9}', username):
            User.USERNAME_FIELD = 'mobile'
        else:
            User.USERNAME_FIELD = 'username'

        from django.contrib.auth import authenticate
        # authenticate用来传递用户名和密码 正确返回信息 错误返回None
        user = authenticate(username=username, password=password)

        if user is None:
            return JsonResponse({'code': 400, 'errmsg': '账号或密码错误'})

        # 4.session
        login(request, user)
        # 判断是否记住登录
        if remembered:
            # 默认是两周
            request.session.set_expiry(None)
        else:
            # 不记住登录 关闭浏览器时session失效
            request.session.set_expiry(0)

        # 5.返回响应
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})
        # 设置首页显示用户信息
        response.set_cookie('username', username)
        from apps.carts.utlis import merge_cookie_to_redis
        response = merge_cookie_to_redis(request,response)

        return response


# 退出登录
class LogOutView(View):

    def delete(self, request):
        logout(request)

        reponse = JsonResponse({'code': 0, 'errmsg': 'ok'})

        reponse.delete_cookie('username')
        return reponse


# 用户中心展示


class CenterView(LoginRequiredJSONMixin, View):

    def get(self, request):
        info_data = ({
            'username': request.user.username,
            'email': request.user.email,
            'mobile': request.user.mobile,
            'email_active': request.user.email_active

        })

        return JsonResponse({'code': 0, 'errmsg': 'ok', 'info_data': info_data})


# ********************************************
# 邮箱
class EmailView(View):

    def put(self, request):
        # 一.添加邮箱
        data = json.loads(request.body.decode())
        email = data.get('email')

        if email is None:
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})

        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}', email):
            return JsonResponse({'code': 400,
                                 'errmsg': '参数email有误'})
        # User
        try:
            # 给email字段赋值
            user = request.user
            user.email = email
            user.save()
        except:
            return JsonResponse({'code': 400, 'errmsg': '添加'})

        # 二.发送邮件
        # subject, message, from_email, recipient_list
        subject = '美多商城激活邮件'
        message = ''
        from_email = '美多商城<user_feng_kai@163.com>'
        # 收件人列表
        recipient_list = ['804515272@qq.com']

        # 获取token
        token = generate_email_verify_token(request.user.id)
        verify_url = "http://www.meiduo.site:8080/success_verify_email.html?token=%s" % token
        # 组织激活邮件
        # a = '激活'
        html_message = '<p>尊敬的用户您好！</p>' \
                       '<p>感谢您使用美多商城。</p>' \
                       '<p>您的邮箱为：%s 。请点击此链接激活您的邮箱：</p>' \
                       '<p><a href="%s">%s<a></p>' % (email, verify_url, verify_url)

        # celery发送邮件
        celery_send_email.delay(
            subject=subject,
            message=message,
            from_email=from_email,
            recipient_list=recipient_list,
            html_message=html_message
        )

        return JsonResponse({'code': 0, 'errmsg': 'ok'})


class EmailVerifyView(View):
    def put(self, requset):
        token = requset.GET.get('token')
        if token is None:
            return JsonResponse({'code': 0, 'errmsg': '参数缺失'})

        # 获取user_id
        user_id = check_email_token(token)
        if user_id is None:
            return JsonResponse({'code': 0, 'errmsg': '参数缺失'})

        user = User.objects.get(id=user_id)
        user.email_active = True
        user.save()

        return JsonResponse({'code': 0, 'errmsg': 'ok'})


# ************修改密码***************

class PasswordView(LoginRequiredJSONMixin, View):

    def put(self, request):
        a = json.loads(request.body.decode())
        old_password = a.get('old_password')
        new_password = a.get('new_password')
        new_password2 = a.get('new_password2')
        b = request.user.check_password(old_password)

        if not all([old_password, new_password, new_password2]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})

        if not b:
            return JsonResponse({'code': 400, 'errmsg': '当前密码错误'})

        if new_password != new_password2:
            return JsonResponse({'code': 400, 'errmsg': '两次密码不一致'})

        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_password):
            return JsonResponse({'code': 400, 'errmsg': '密码格式不对'})

        # 修改密码
        request.user.set_password(new_password)
        request.user.save()

        # 清理缓存
        logout(request)

        a = JsonResponse({'code': 0, 'errmsg': 'ok'})
        a.delete_cookie('username')

        return a

from django_redis import get_redis_connection
class HistoryView(LoginRequiredJSONMixin, View):
    """用户浏览记录 """

    # 获取数据
    def post(self, request):
        user_id = request.user.id
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')

        # 验证数据
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse({'code': 400, 'errmsg': '商品不存在'})

        # 链接redis
        redis_cli = get_redis_connection('history')
        # 5. 去重(先删除 这个商品id 数据，再添加就可以了)
        redis_cli.lrem('history_%s' % user_id, 0, sku_id)
        # 6. 保存到redis中
        redis_cli.lpush('history_%s' % user_id, sku_id)
        # 7. 只保存5条记录
        redis_cli.ltrim("history_%s" % user_id, 0, 4)

        return JsonResponse({'code': 0, 'errmsg': 'ok'})

    def get(self, request):
        user_id = request.user.id
        redis_cli = get_redis_connection('history')

        ids = redis_cli.lrange('history_%s' % user_id, 0, 4)

        # 组织数据
        history_list = []
        for sku_id in ids:
            sku = SKU.objects.get(id=sku_id)
            history_list.append({
                'id': sku.id,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price
            })

        return JsonResponse({'code': 0, 'errmsg': 'ok', 'skus': history_list})





